package com.threefivework.mymall.controller;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.threefivework.mymall.model.domain.PaymentRecord;
import com.threefivework.mymall.model.domain.TradeDTO;
import com.threefivework.mymall.service.PaymentRecordService;
import com.threefivework.mymall.service.PaymentService;
import com.threefivework.mymall.service.WechatClient;
import com.threefivework.mymall.util.IpUtil;
import com.threefivework.mymall.util.XmlUtil;
import com.threefivework.mymall.wechat.constant.WXPayConstants;
import com.threefivework.mymall.wechat.util.WXPayUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * descripiton: 微信支付控制器
 *
 * @author: kinson(2219945910@qq.com)
 * @date: 2018/6/27
 * @time: 1:07
 * @modifier:
 * @since:
 */
@Controller
@RequestMapping("/payment")
public class PayController {

    private static final Logger logger = LoggerFactory.getLogger(PayController.class);

    @Autowired
    private WechatClient wechatClient;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private PaymentRecordService paymentRecordService;

    @RequestMapping(value = "test")
    @ResponseBody
    public String testClient() {
        return wechatClient.test();
    }

    @RequestMapping(value = "/confirm/pay", method = RequestMethod.POST)
    @ResponseBody
    public String confirmPay(@RequestBody TradeDTO tradeDTO,
                             HttpServletRequest request) throws Exception {
        logger.info("================开始预支付================");
        String clientIP = IpUtil.getClientIP(request);
        tradeDTO.setClientIP(clientIP);
        return paymentService.unifiedOrder(tradeDTO);
    }

    @RequestMapping(value = "/wxpay/notify", method = RequestMethod.POST)
    @ResponseBody
    public String notify(HttpServletRequest request, HttpServletResponse response) {
        logger.info("================开始支付回调================");
        String clientIP = IpUtil.getClientIP(request);

        InputStream inputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        PrintWriter writer = null;
        try {
            inputStream = request.getInputStream();
            byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, len);
            }

            String callbackXml = new String(byteArrayOutputStream.toByteArray(), "utf-8");
            //processResponseXml该方法已做过二次签名校验
            Map<String, String> xmlMap = XmlUtil.processResponseXml(callbackXml);
            Map<String, String> respMap = Maps.newHashMap();
            writer = response.getWriter();
            if (xmlMap.isEmpty() || xmlMap.containsKey(WXPayConstants.FIELD_RETURN_CODE)) {
                respMap.put(WXPayConstants.FAIL, "error");
            } else {
                if (StringUtils.equals(WXPayConstants.SUCCESS, xmlMap.get(WXPayConstants.FIELD_RETURN_CODE))) {
                    respMap.put(WXPayConstants.SUCCESS, "");
                    writer.write(WXPayUtil.mapToXml(respMap));
                    if (xmlMap.containsKey(WXPayConstants.FIELD_RESULT_CODE)
                            && StringUtils.equals(WXPayConstants.SUCCESS, xmlMap.get(WXPayConstants.FIELD_RESULT_CODE))) {
                        return paymentService.notify(xmlMap, callbackXml);
                    }
                } else {
                    respMap.put(WXPayConstants.FAIL, "error");
                    writer.write(WXPayUtil.mapToXml(respMap));
                }
            }
        } catch (Exception e) {
            logger.error("================支付回调异常================");
        } finally {
            //关闭流
            IOUtils.closeQuietly(inputStream);
            IOUtils.closeQuietly(byteArrayOutputStream);
            IOUtils.closeQuietly(writer);
        }
        return WXPayConstants.FAIL;
    }

    @RequestMapping(value = "ibatis", method = RequestMethod.GET)
    @ResponseBody
    public Object testIbatis(String type) {
        if (StringUtils.isEmpty(type)) {
            return paymentRecordService.listPaymentRecord();
        } else {
            return paymentRecordService.getPaymentRecordByPK(Integer.valueOf(type));
        }
    }

    @RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
    @ResponseBody
    public Object delete(@PathVariable String id) {
        System.out.println(id);
        paymentRecordService.delete(Integer.valueOf(id));
        return "delete suc";
    }

    @RequestMapping(value = "insert", method = RequestMethod.POST)
    @ResponseBody
    public Object insert(@RequestBody PaymentRecord paymentRecord) {
       try {
           return paymentRecordService.insert(paymentRecord);
       } catch (Throwable e) {
           logger.error("[PayController] insert异常", e);
           return e.getMessage();
       }
    }

    @RequestMapping(value = "/batch/insert", method = RequestMethod.POST)
    @ResponseBody
    public Object batchInsert(@RequestBody List<PaymentRecord> paymentRecords) {
        try {
            return paymentRecordService.batchInsert(paymentRecords);
        } catch (Throwable e) {
            logger.error("[PayController] batchInsert异常", e);
            return e.getMessage();
        }
    }
}
